<template>
  <div class="page-container">
    <div class="in-container">
      <div style="width: 70%">
        <AppSearchForm @submit="search()" @reset="reset()">
          <el-form-item prop="name">
            <el-input v-model="query.name" placeholder="输入角色名称搜索">
            </el-input>
          </el-form-item>
          <el-form-item prop="date">
            <el-date-picker
              v-model="query.date"
              type="daterange"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
            />
          </el-form-item>
        </AppSearchForm>
        <div class="BtnBox">
          <el-button @click="toCreate" type="primary">添加角色</el-button>
        </div>
        <AppPageTable
          stripe
          :data="tableData.data"
          :autostyle="'height: calc(100% - 64px);'"
          :option="tableData.option"
          :singleHighLight="true"
          layout="total, prev, pager, next"
          size="small"
          @change="getList()"
          @singleClick="tableSinClick($event)"
        >
          <el-table-column prop="name" label="角色名称" />
          <el-table-column prop="permission" label="角色代码" />
          <el-table-column prop="dataScope" label="数据权限" />
          <el-table-column
            :show-overflow-tooltip="true"
            prop="description"
            label="描述"
          />
          <el-table-column
            :show-overflow-tooltip="true"
            width="200px"
            prop="createTime"
            label="创建日期"
          />
          <el-table-column width="170px" label="操作">
            <template #default="scope">
              <el-button @click.stop="handleEdit(scope.row)" link type="primary"
                >编辑</el-button
              >
              <!-- <el-button @click.stop="editUserList(scope.row, scope.$index)" link type="primary">添加用户</el-button> -->
              <el-button
                @click.stop="handleRemove(scope.row)"
                link
                type="danger"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </AppPageTable>
      </div>
      <div class="rightMenu">
        <el-tabs type="card" v-model="activeName">
          <!-- 权限列表 -->
          <el-tab-pane label="权限列表" name="RightList">
            <div v-show="activeName === 'RightList'">
              <div class="header">
                <span class="title"> 权限管理 </span>

                <el-button
                  type="primary"
                  size="small"
                  :loading="menu.loading"
                  :disabled="!menu.isClick"
                  @click="saveMenu"
                >
                  保存
                </el-button>
              </div>
              <div class="content">
                <div v-show="!menu.isClick">点击数据以显示授权数据</div>
                <div style="height: 100%" v-show="menu.isClick">
                  <el-tree
                    ref="menu"
                    lazy
                    :data="menus"
                    :default-checked-keys="menuIds"
                    :load="getMenuDatas"
                    :props="defaultProps"
                    check-strictly
                    accordion
                    show-checkbox
                    node-key="id"
                    @check="menuChange"
                  />
                </div>
              </div>
            </div>
          </el-tab-pane>
          <!-- 用户列表 -->
          <el-tab-pane label="用户列表" name="UserList">
            <div v-show="!menu.isClick">点击数据以显示授权数据</div>
            <div v-show="menu.isClick && activeName === 'UserList'">
              <div class="header">
                <span class="title">人员管理</span>
                <div>
                  <el-button
                    type="primary"
                    size="small"
                    @click.stop="editUserList(this.currentItem)"
                  >
                    添加用户
                  </el-button>

                  <el-popconfirm
                    title="确定删除所选数据吗？"
                    @confirm="deleteUserList(this.currentItem)"
                  >
                    <template #reference>
                      <el-button type="danger" size="small">
                        删除所选用户
                      </el-button>
                    </template>
                  </el-popconfirm>
                </div>
              </div>
              <div class="content">
                <AppSearchForm
                  size="small"
                  @submit="userSearch()"
                  @reset="userReset()"
                >
                  <el-form-item>
                    <el-input
                      v-model="userQuery.name"
                      clearable
                      placeholder="请输入用户名称"
                    />
                  </el-form-item>
                </AppSearchForm>
                <AppPageTable
                  stripe
                  :data="userTableNew.data"
                  :autostyle="'height: calc(100% - 64px);'"
                  :option="userTableNew.option"
                  layout="total, prev, pager, next"
                  size="small"
                  ref="userTableNew"
                >
                  <el-table-column type="selection" width="50px" />
                  <el-table-column prop="username" label="账号" />
                  <el-table-column prop="nickName" label="昵称" />
                  <el-table-column prop="phone" label="手机号" />
                  <el-table-column prop="gender" label="性别" />
                </AppPageTable>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
    <el-dialog
      width="500px"
      v-model="dialogData.show"
      :title="dialogData.title"
    >
      <el-form
        :model="role"
        :rules="roleRules"
        label-width="80px"
        ref="roleForm"
      >
        <el-form-item prop="name" label="角色名称">
          <el-input v-model="role.name" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item prop="permission" label="角色代码">
          <el-input
            v-model="role.permission"
            placeholder="请输入角色代码"
          ></el-input>
        </el-form-item>
        <el-form-item prop="dataScope" label="数据范围">
          <el-select v-model="role.dataScope" placeholder="请选择数据范围">
            <el-option v-for="item in dateScopes" :key="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item prop="description" label="描述信息">
          <el-input type="textarea" v-model="role.description"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelDialog" link>取消</el-button>
          <el-button
            type="primary"
            @click="submitDialog"
            :loading="dialogData.loading"
          >
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
    <userRoleDialog
      :roleId="toRoleId"
      v-model:userList="userList"
      v-model:dialog="userListDialog"
      @toChangeUserList="saveToUserList"
      @ok="getUserListNew"
    >
    </userRoleDialog>
  </div>
</template>

<script>
import { defineComponent } from "vue";
import dayjs from "dayjs";
import AppSearchForm from "@/components/AppSearchForm.vue";
import AppPageTable, { useTableOption } from "@/components/AppPageTable2";
import userRole from "./components/userRole.vue";
import userRoleDialog from "./components/userRoleDialog.vue";
export default defineComponent({
  components: {
    AppSearchForm,
    AppPageTable,
    AppSearchForm,
    userRole,
    userRoleDialog,
  },
  data() {
    return {
      tableData: {
        data: [],
        option: useTableOption(),
      },
      query: {
        name: "",
        date: [],
      },
      //查询用户所用条件
      userQuery: {
        name: "",
        date: [],
      },
      dialogData: {
        show: false,
        title: "新增角色",
        loading: false,
      },
      role: {
        name: "",
        permission: "",
        //角色级别 统一为1
        level: 1,
        dataScope: "全部",
        description: "",
      },
      roleRules: {
        name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
        permission: [
          { required: true, message: "请输入角色代码", trigger: "blur" },
        ],
      },
      dateScopes: ["全部", "本级", "本人"],
      menu: {
        isClick: false,
        tree: [],
        loading: false,
        defaultProps: { children: "children", label: "label" },
        menus: [],
        dataID: "",
      },

      // emptyMenu: [],
      currentId: 0,
      menus: [],
      menuIds: [],
      // userIds: [],
      defaultProps: { children: "children", label: "label", isLeaf: "leaf" },
      //授权用户弹窗数据
      userListDialog: {
        show: false,
        btnLoading: false,
      },
      //编辑角色授权用户时 保存该角色的授权用户数据
      userList: [],
      //编辑角色授权用户时 保存该角色的授权用户数据下标
      userListIndex: 0,
      //编辑角色授权用户时 保存该角色id
      toRoleId: "",
      //默认激活tab
      activeName: "RightList",
      userTable: {
        data: [],
        option: useTableOption(),
      },
      //用户表格
      userTableNew: {
        data: [],
        option: useTableOption(),
      },
      //保存点击的角色信息
      currentItem: {},
    };
  },
  methods: {
    /**
     * 获取表格详细
     */
    getList() {
      let url = "/api/role/query";
      if (this.query.date.length > 0) {
        this.query.date[0] = dayjs(this.query.date[0]).format(
          "YYYY-MM-DD HH:mm:ss"
        );
        this.query.date[1] = dayjs(this.query.date[1])
          .add(1, "day")
          .subtract(1, "second")
          .format("YYYY-MM-DD HH:mm:ss");
        url =
          url +
          `?CreateTime=${this.query.date[0]}&CreateTime=${this.query.date[1]}`;
      }
      this.tableData.option.loading = true;
      this.$http
        .get(url, {
          PageIndex: this.tableData.option.page,
          PageSize: this.tableData.option.pageSize,
          RoleName: this.query.name,
        })
        .then((res) => {
          this.tableData.data = res.content;
          this.tableData.option.total = res.totalElements;
        })
        .finally(() => {
          this.tableData.option.loading = false;
        });
    },
    /**
     * 查询
     */
    search() {
      this.tableData.option.page = 1;
      this.getList();
    },
    /**
     * 重置
     */
    reset() {
      this.query = {
        name: "",
        date: [],
      };
      this.tableData.option.page = 1;
      this.getList();
    },
    /**
     * 添加角色
     */
    toCreate() {
      this.dialogData.show = true;
      this.dialogData.title = "新增角色";
    },
    /**
     * 编辑
     * @param {Object} row - 行数据
     */
    handleEdit(row) {
      this.role = JSON.parse(JSON.stringify(row));
      this.dialogData.title = "修改角色";
      this.dialogData.show = true;
    },
    /**
     * 删除
     * @param {Object} row - 行数据
     */
    async handleRemove(row) {
      this.$confirm("确定删除该角色?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(async () => {
        const res = await this.$http.post("/api/role/delete", {
          idArray: [row.id],
        });
        if (res.status) {
          this.$message({
            message: "成功",
            type: "success",
          });
          this.getList();
        } else {
          this.$message({
            type: "error",
            message: res.message,
          });
        }
      });
    },
    // handleSizeChange() {
    //   this.tableData.currentPage = 1;
    //   this.getList();
    // },
    // handleCurrentChange() {
    //   this.getList();
    // },
    tableSinClick(val) {
      this.menu.isClick = true;
      this.currentItem = val;
      if (val) {
        // 清空菜单的选中
        this.$refs.menu.setCheckedKeys([]);
        // 保存当前的角色id
        this.currentId = val.id;
        // 初始化默认选中的key
        this.menuIds = [];
        val.menus.forEach((data) => {
          this.menuIds.push(data.id);
        });
        this.getUserListNew();
      }
    },
    menuChange(menu) {
      // 获取该节点的所有子节点，id 包含自身
      if (this.menuIds.indexOf(menu.parentId) == -1) {
        this.menuIds.push(menu.parentId);
      }
      this.$http.get("api/menu/child?id=" + menu.id).then((childIds) => {
        // 判断是否在 menuIds 中，如果存在则删除，否则添加
        if (this.menuIds.indexOf(menu.id) !== -1) {
          for (let i = 0; i < childIds.length; i++) {
            const index = this.menuIds.indexOf(childIds[i]);
            if (index !== -1) {
              this.menuIds.splice(index, 1);
            }
          }
        } else {
          for (let i = 0; i < childIds.length; i++) {
            const index = this.menuIds.indexOf(childIds[i]);
            if (index === -1) {
              this.menuIds.push(childIds[i]);
            }
          }
        }
        this.$refs.menu.setCheckedKeys(this.menuIds);
      });
    },
    // 保存菜单
    saveMenu() {
      this.menu.loading = true;
      const role = { id: this.currentId, menus: [] };
      // 得到已选中的 key 值
      this.menuIds.forEach(function (id) {
        const menu = { id: id };
        role.menus.push(menu);
      });
      this.$http.post("api/role/menu/edit", role).then((res) => {
        if (res.status) {
          this.$message.success(res.message);
          this.getList();
        } else {
          this.$message.error(res.message);
        }
        this.menu.loading = false;
      });
    },
    getMenuDatas(node, resolve) {
      let url = node.data.id ? node.data.id : 0;
      this.$http.get("api/menu/lazy?pid=" + url).then((res) => {
        resolve(res);
      });
    },
    cancelDialog() {
      this.dialogData.show = false;
    },
    submitDialog() {
      let url = "";
      if (this.role.id) {
        url = "/api/role/edit";
      } else {
        url = "/api/role/create";
      }
      this.$refs.roleForm.validate((valid) => {
        if (valid) {
          this.dialogData.loading = true;
          this.$http.post(url, this.role).then((res) => {
            this.dialogData.loading = false;
            if (res.status) {
              this.$message.success(res.message ?? "成功");
              this.getList();
              this.dialogData.show = false;
            } else {
              this.$message.error(res.message ?? "`服务器错误");
            }
          });
        }
      });
    },
    /**
     * 修改角色的用户数据
     */
    editUserList(val) {
      this.userListIndex = val.index;
      this.toRoleId = val.id;
      this.userListDialog.show = true;
    },
    saveToUserList() {
      this.tableData.data[this.userListIndex].user = this.userList;
    },
    /**
     * 查询用户信息
     */
    userSearch() {
      this.userTableNew.option.page = 1;
      this.getUserListNew();
    },
    /**
     * 重置查询条件
     */
    userReset() {
      this.userTableNew.option.page = 1;
      this.userQuery.name = "";
      this.getUserListNew();
    },
    /**
     * 获取已授权用户列表
     */
    getUserListNew() {
      this.$http
        .get("/api/userRole/query", {
          roleId: this.currentId,
          keyWords: this.userQuery.name,
        })
        .then((res) => {
          this.userTableNew.data = res.content;
          this.userList = res.content;
          this.userTableNew.option.total = res.totalElements;
        });
    },
    /**
     * 删除已授权用户
     */
    deleteUserList() {
      this.$http
        .post("/api/userRole/delUserRole", {
          roleId: this.currentId,
          userIdList: this.userTableNew.option.selected.map((t) => {
            return t.id;
          }),
        })
        .then((res) => {
          if (res.status) {
            this.$message.success(res.message);
          } else {
            this.$message.error(res.message);
          }
        })
        .finally(() => {
          this.getUserListNew();
        });
    },
  },

  watch: {
    "dialogData.show"(newVal) {
      if (!newVal) {
        this.role = {
          name: "",
          permission: "",
          level: 1,
          dataScope: "全部",
          description: "",
        };
        this.$nextTick(() => {
          // this.$refs.roleForm.resetFields();
          this.$refs.roleForm.clearValidate();
        });
      }
    },
  },
  created() {
    this.getList();
  },
  mounted() {},
});
</script>

<style lang="scss" scoped>
.in-container {
  display: flex;
}

.BtnBox {
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
}

.roleBox {
  width: 100%;
  height: 100%;
}

.TableBox :deep(.tableHeader) th {
  background-color: #f7f8fa !important;
}

.tableheight {
  height: 100%;
}

.rightMenu {
  flex: 1;
  margin-left: 10px;
  margin-top: 64px;
  border: 1px solid #e6ebf5;

  .header {
    background: #f7f8fa;
    padding: 8px;
    border-bottom: 1px solid #e6ebf5;
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 40px;

    .title {
      font-weight: 700;
      color: #909399;
      font-size: 12px;
      transition: all 0.5s;
      cursor: pointer;
    }
  }

  .content {
    padding: 8px;
    height: calc(100% - 40px);
    overflow-y: auto;
  }
}

.menu-title-active {
  color: #409eff !important;
}
</style>
